<template>
  <div class="chart"
       ref="baseEchartRef"
       :style="{ ...echartStyle }"></div>
</template>

<script setup>
import * as echarts from "echarts/core";
import { computed, watch, ref, onUnmounted, nextTick, onMounted } from "vue";
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  VisualMapComponent,
  DataZoomComponent,
} from "echarts/components";
import {
  BarChart,
  LineChart,
  PieChart,
  // MapChart,
  ScatterChart,
} from "echarts/charts";
import { CanvasRenderer } from "echarts/renderers";
import { throttle } from "@/utils/throttle";

echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  CanvasRenderer,
  // MapChart,
  VisualMapComponent,
  ScatterChart,
  BarChart,
  LineChart,
  PieChart,
  DataZoomComponent,
]);

const props = defineProps({
  // 图表宽度
  width: { type: String, default: "100%" },
  // 图表高度
  height: { type: String, default: "100%" },
  // 图表配置项
  options: { type: Object, default: () => ({}) },
  // 点击事件的对象
  eventObj: { type: Object, default: () => ["series"] },
  // 初始化前函数
  beforeInit: { type: Function, default: undefined },
  // 更新数据前的函数
  beforeUpdate: { type: Function, default: undefined },
  // 更新当前图层数据
  isUpdate: { type: Boolean, default: true },
  // 循环渲染
  autoRander: { type: Boolean, default: false },
  // 循环渲染间隔 单位S
  autoNumber: { type: Number, default: 60 },
});

const emit = defineEmits(["click"]);

const baseEchartRef = ref(null);

let baseChart = null;

let timer = {
  intervalTimer: null,
  randerTimer: null,
  initTimer: null,
};

// 设置图表宽高
const echartStyle = computed(() => {
  const { width, height } = props;
  // 判断是否已%或者rem结尾
  const reg1 = /%$/;
  const reg2 = /rem$/;

  let result = {
    width: reg1.test(width) || reg2.test(width) ? width : `${width}px`,
    height: reg1.test(height) || reg2.test(height) ? height : `${height}px`,
  };
  return result;
});

watch(
  () => props.options,
  () => {
    // timer.randerTimer = setTimeout(async () => {
    //   if (props.beforeInit) {
    //     await props.beforeInit();
    //   }
    //   nextTick(() => {
    //     initChart();
    //   });
    // }, 500);

    // if (props.autoRander) {
    //   timer.intervalTimer = setInterval(() => {
    //     // 清除图例及组件
    //     baseChart && baseChart.clear();
    //     // 渲染数据
    //     randerEchart(props.options);
    //   }, props.autoNumber * 1000);
    // }
  },
  { deep: true }
);

onMounted(() => {
  setTimeout(async () => {
    // if (props.beforeInit) {
    //   await props.beforeInit();
    // }
    nextTick(() => {
      initChart();
    });
  }, 500);
});

onUnmounted(() => {
  window.removeEventListener("resize", throttle(resizeFn, 500));
  timer = {
    intervalTimer: null,
    randerTimer: null,
    initTimer: null,
    sizeTimer: null,
  };
});

// 初始化图表实例
const initChart = () => {
  if (!baseChart) {
    // 初始化实例
    baseChart = echarts.init(baseEchartRef.value);
  }

  randerEchart(props.options);

  // 浏览器缩放
  window.addEventListener("resize", throttle(resizeFn, 500));
  if (props.eventObj.length) {
    props.eventObj.forEach((v) => {
      // 图形点击事件
      baseChart.on("click", v, (params) => {
        emit("click", { params, chartRef: baseChart });
      });
    });
  }

  // 监听 legendselectchanged 事件
  baseChart.on("legendselectchanged", (event) => {
    emit("legendselectchanged", event);
  });
};

// 渲染图表
const randerEchart = async (options) => {
  if (baseChart) {
    // 清除画布
    baseChart.clear();
    // 更新数据前的操作
    if (props.beforeUpdate) {
      await props.beforeUpdate();
    }
    baseChart.setOption(options, props.isUpdate);
  }
};

const resizeFn = () => {
  timer.sizeTimer = setTimeout(() => {
    baseChart && baseChart.resize();
  }, 100);
};

const reloadEchart = () => {
  if (!baseChart) {
    initChart();
    return;
  }
  baseChart && baseChart.resize();
};

// 用于父组件使用echarts实例
const commonFunc = (callback) => {
  callback && callback(baseChart);
};

// 抛出属性或者方法供父组件使用
defineExpose({ commonFunc, randerEchart, reloadEchart });
</script>

<style lang="less">
.echart-popover {
  background-image: linear-gradient(
    180deg,
    rgba(0, 0, 0, 0.9),
    rgba(0, 134, 205, 0.91)
  );
}
</style>